
#ifndef __H_SYMPHONY_OBJECT
#define __H_SYMPHONY_OBJECT

#include "keywords.h"
#include "world.h"

// Object types...
#define OTYPE_UNDEFINED 0
#define OTYPE_TRASH     1
#define OTYPE_CONTAINER 2
#define OTYPE_WEAPON    3
#define OTYPE_ARMOR     4
#define OTYPE_KEY       5

// Object composition flags...
#define OCOMP_UNDEFINED 0
#define OCOMP_WOOD      A
#define OCOMP_PAPER     B
#define OCOMP_IRON      C
#define OCOMP_LEATHER   D



/************************************************************ BASE OBJECT ************************************************************/

#define OFLAG_UNDEFINED 0
#define OFLAG_NOREMOVE  A
#define OFLAG_NODROP    B
#define OFLAG_MELTDROP  C
#define OFLAG_GLOWING   D
#define OFLAG_HUMMING   E

class Object: public Keywords {
  private:
    unsigned long     _ID;
    unsigned short    _type;
    std::string       _strtype;
    unsigned long     _vnum;
    unsigned long     _basicFlags;
    unsigned long     _flags;
    unsigned long     _composition;
    unsigned short    _level;
    unsigned short    _value;
    std::string       _shortname;
    std::string       _description;

  public:
    // Constructors...
    Object( void );
    Object( Area* area, const unsigned long& vnum, const unsigned short& type );
    Object( const Object& ref );
    Object( ROW row );
    virtual ~Object( void );

    // Public accessor methods...
    void              ID( const unsigned long& ID )                               { _ID = ID; }
    unsigned long     ID( void ) const                                            { return _ID; }
    void              type( const unsigned short& type );
    unsigned short    type( void ) const                                          { return _type; }
    void              strtype( const std::string& strtype )                       { _strtype = strtype; }
    std::string       strtype( void ) const                                       { return _strtype; }
    void              vnum( const unsigned long& vnum )                           { _vnum = vnum; }
    unsigned long     vnum( void ) const                                          { return _vnum; }
    void              basicFlags( const unsigned long& basicFlags )               { _basicFlags = basicFlags; }
    unsigned long     basicFlags( void ) const                                    { return _basicFlags; }
    void              flags( const unsigned long& flags )                         { _flags = flags; }
    unsigned long     flags( void ) const                                         { return _flags; }
    void              composition( const unsigned long& composition )             { _composition = composition; }
    unsigned long     composition( void ) const                                   { return _composition; }
    void              level( const unsigned short& level )                        { _level = level; }
    unsigned short    level( void ) const                                         { return _level; }
    void              value( const unsigned short& value )                        { _value = value; }
    unsigned short    value( void ) const                                         { return _value; }
    void              shortname( const std::string& shortname )                   { _shortname = shortname; }
    std::string       shortname( void ) const                                     { return _shortname; }
    void              description( const std::string& description )               { _description = description; }
    std::string       description( void ) const                                   { return _description; }

    // General methods...
    void              basicFlag( const unsigned long& flag, const bool& value )   { basicFlags( value ? (basicFlags()|flag) : (basicFlags()&(~flag)) ); }
    bool              basicFlag( const unsigned long& flag )                      { return ( (basicFlags()&flag) == flag ); }
    void              flag( const unsigned long& flag, const bool& value )        { flags( value ? (flags()|flag) : (flags()&(~flag)) ); }
    bool              flag( const unsigned long& flag )                           { return ( (flags()&flag) == flag ); }
    void              comp( const unsigned long& comp, const bool& value )        { composition( value ? (composition()|comp) : (composition()&(~comp)) ); }
    bool              comp( const unsigned long& comp )                           { return ( (composition()&comp) == comp ); }
    std::string       listComposition( void );
    std::string       listBasicFlags( void );
    std::string       listFlags( void );
    void              save( void );
    bool              destroy( void );

    // Static methods...
    static Object*          create( Area* area, const unsigned long& vnum, const unsigned short& type );
    static Object*          create( const unsigned short& type, ROW row );
    static Object*          create( Object* src );
    static std::string      getInformation( Object* object );
    static unsigned short   getType( const std::string& t );
    static std::string      getType( const unsigned short& t );
    static const char*      getFlagName( const unsigned long& flag, unsigned short type = OTYPE_UNDEFINED );
    static unsigned long    getFlagType( const std::string& name, unsigned short type = OTYPE_UNDEFINED );
    static const char*      getCompositionName( const unsigned long& composition );
    static unsigned long    getCompositionType( const std::string& composition );

};

/************************************************************ TRASH ************************************************************/
class ObjTrash: public Object {
  private:

  public:
    // Constructors...
    ObjTrash( void );
    ObjTrash( Area* area, const unsigned long& vnum, const unsigned short& type );
    ObjTrash( const ObjTrash& ref );
    ObjTrash( ROW row );
    ~ObjTrash( void );

};

/************************************************************ CONTAINER ************************************************************/

#define OFLAG_CLOSEABLE A
#define OFLAG_CLOSED    B
#define OFLAG_LOCKABLE  C
#define OFLAG_LOCKED    D
#define OFLAG_BURNPROOF E

class ObjContainer: public Object {
  private:
    std::list<Object*>            _objects;

  public:
    // Constructors...
    ObjContainer( void );
    ObjContainer( Area* area, const unsigned long& vnum, const unsigned short& type );
    ObjContainer( const ObjContainer& ref );
    ObjContainer( ROW row );
    ~ObjContainer( void );

    // Public accessor methods...
    std::list<Object*>&           objects( void )                   { return _objects; }
    const std::list<Object*>&     objects( void ) const             { return _objects; }

    // General methods...
    void                          add( Object* object )             { objects().push_back( object ); }
    void                          remove( Object* object )          { objects().remove( object ); }
    Object*                       find( const std::string& name );

};

/************************************************************ WEAPON ************************************************************/

#define OFLAG_SHARP     A
#define OFLAG_SHOCKING  B
#define OFLAG_BURNING   C
#define OFLAG_FREEZING  D

class ObjWeapon: public Object {
  private:

  public:
    // Constructors...
    ObjWeapon( void );
    ObjWeapon( Area* area, const unsigned long& vnum, const unsigned short& type );
    ObjWeapon( const ObjWeapon& ref );
    ObjWeapon( ROW row );
    ~ObjWeapon( void );

};

/************************************************************ ARMOR ************************************************************/
class ObjArmor: public Object {
  private:

  public:
    // Constructors...
    ObjArmor( void );
    ObjArmor( Area* area, const unsigned long& vnum, const unsigned short& type );
    ObjArmor( const ObjArmor& ref );
    ObjArmor( ROW row );
    ~ObjArmor( void );

};

/************************************************************ KEY ************************************************************/
class ObjKey: public Object {
  private:

  public:
    // Constructors...
    ObjKey( void );
    ObjKey( Area* area, const unsigned long& vnum, const unsigned short& type );
    ObjKey( const ObjKey& ref );
    ObjKey( ROW row );
    ~ObjKey( void );

};



#endif // #ifndef __H_SYMPHONY_OBJECT

